package cn.ljw.mybatis;

import cn.ljw.mybatis.Configuration;
import cn.ljw.mybatis.MapperProxyFactory;
import cn.ljw.mybatis.XNode;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.Map;

//package cn.ljw.mybatis;
//
//import lombok.RequiredArgsConstructor;
//import lombok.SneakyThrows;
//
//import java.io.Serializable;
//import java.lang.invoke.MethodHandle;
//import java.lang.invoke.MethodHandles;
//import java.lang.reflect.Constructor;
//import java.lang.reflect.InvocationHandler;
//import java.lang.reflect.InvocationTargetException;
//import java.lang.reflect.Method;
//import java.util.HashMap;
//import java.util.Map;
//
///**
// * @author 一朝风月
// * @date 2024/9/21 21:21
// * @Code 面向注解面向卿，终无解释再无你
// * @description通过 MapperProxyFactory 创建了一个 MapperProxy 的实例，
// * 这个实例实现了 InvocationHandler 接口，从而实现了 JDK 动态代理。 设计模式工厂
// */
//
//public class MapperProxy<T> implements InvocationHandler, Serializable {
//    //mapper调用接口执行调用代理启动
//    interface MapperMethodInvoker {
//        Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable;
//    }
//    private final Map<Method, MapperMethodInvoker> invokerCache = new HashMap<>();
//    private static final long serialVersionUID= -6887279226904669832L;
//    private static final int ALLOWED_MODES = 15;
//    private static final Constructor<MethodHandles.Lookup> lookupConstructor ;
//    private static final Method privateLookupInMethod;//
//
//    private final Map<Method, MapperMethodInvoker> methodCache;
//    private final SqlSession sqlSession;
//    private final Class<T> mapperInterface;
//    public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethodInvoker> methodCache) {
//        this.sqlSession = sqlSession;
//        this.mapperInterface = mapperInterface;
//        this.methodCache = methodCache;
//    }
//    @SneakyThrows
//    @Override
//    public Object invoke(Object proxy, Method method, Object[] args)  {
//        if (Object.class.equals(method.getDeclaringClass())) {
//            return Object.class.equals(method.getDeclaringClass()) ? method.invoke(this, args) : this.cachedInvoker(method).invoke(proxy, method, args, this.sqlSession);
//        }
//
//    }
//
//    /**
//     * 缓存方法
//     * @param method
//     * @return
//     */
//
//    // 缓存方法调用器
//
//
//    /**
//     * 获取缓存的方法调用器。
//     * 如果方法调用器不存在，则创建一个新的实例并缓存。
//     *
//     * @param method 要调用的方法
//     * @return 方法调用器
//     */
//    public MapperMethodInvoker cachedInvoker(Method method) {
//        // 从缓存中获取方法调用器
//        MapperMethodInvoker invoker = methodCache.get(method);
//
//
//        return invoker;
//    }
//    private static class DefaultMethodInvoker implements MapperMethodInvoker {
//        private final MethodHandle methodHandle;
//
//        public DefaultMethodInvoker(MethodHandle methodHandle) {
//            this.methodHandle = methodHandle;
//        }
//
//        public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
//            return this.methodHandle.bindTo(proxy).invokeWithArguments(args);
//        }
//    }
//
//    private static class PlainMethodInvoker implements MapperMethodInvoker {
//        private final MapperMethod mapperMethod;
//
//        public PlainMethodInvoker(MapperMethod mapperMethod) {
//            this.mapperMethod = mapperMethod;
//        }
//
//        public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
//            return this.mapperMethod.execute(sqlSession, args);
//        }
//    }
//
//
//    /**
//     * 处理jdk8动态代理的调用
//     * @param method
//     * @return
//     * @throws IllegalAccessException
//     * @throws InstantiationException
//     * @throws InvocationTargetException
//     */
//    private MethodHandle getMethodHandleJava8(Method method) throws IllegalAccessException, InstantiationException, InvocationTargetException {
//        Class<?> declaringClass = method.getDeclaringClass();
//        return ((MethodHandles.Lookup)lookupConstructor.newInstance(declaringClass, 15)).unreflectSpecial(method, declaringClass);
//    }
//}
@AllArgsConstructor
@NoArgsConstructor
public class MapperProxy<T> implements InvocationHandler, Serializable {

    private Configuration configuration;
    private Connection connection;
    private Map<String, XNode> mapperElement;

    public static <T> Object newInstance(Class<T> type, MapperProxy winterFlySqlSession) {
        return Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[]{type}, winterFlySqlSession);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return null;

    }
}